
namespace col {

////////////////////////////////////////////////////////////////////////////////
// Vector3f

inline Vector3f::Vector3f()
:
#ifndef __GNUC__
    d(0.0),
#endif
    mX(0.0),
    mY(0.0),
    mZ(0.0)
{}

inline Vector3f::Vector3f( const Vector3f &vec )
{
    mX = vec.mX;
    mY = vec.mY;
    mZ = vec.mZ;
}

inline Vector3f::Vector3f( float _x, float _y, float _z )
{
    mX = _x;
    mY = _y;
    mZ = _z;
}

inline Vector3f::Vector3f( const Point3f &pnt )
{
    mX = pnt.getX();
    mY = pnt.getY();
    mZ = pnt.getZ();
}

inline Vector3f::Vector3f( float scalar )
{
    mX = scalar;
    mY = scalar;
    mZ = scalar;
}

inline Vector3f& Vector3f::operator =( const Vector3f &vec )
{
    mX = vec.mX;
    mY = vec.mY;
    mZ = vec.mZ;
    return *this;
}

inline Vector3f& Vector3f::setX( float _x )
{
    mX = _x;
    return *this;
}

inline float Vector3f::getX( ) const
{
    return mX;
}

inline Vector3f& Vector3f::setY( float _y )
{
    mY = _y;
    return *this;
}

inline float Vector3f::getY( ) const
{
    return mY;
}

inline Vector3f& Vector3f::setZ( float _z )
{
    mZ = _z;
    return *this;
}

inline float Vector3f::getZ( ) const
{
    return mZ;
}

inline Vector3f& Vector3f::setElem( int idx, float value )
{
    *(&mX + idx) = value;
    return *this;
}

inline float Vector3f::getElem( int idx ) const
{
    return *(&mX + idx);
}

inline float& Vector3f::operator []( int idx )
{
    return *(&mX + idx);
}

inline float Vector3f::operator []( int idx ) const
{
    return *(&mX + idx);
}

inline const Vector3f Vector3f::operator +( const Vector3f &vec ) const
{
    return Vector3f(
        ( mX + vec.mX ),
        ( mY + vec.mY ),
        ( mZ + vec.mZ )
    );
}

inline const Vector3f Vector3f::operator -( const Vector3f &vec ) const
{
    return Vector3f(
        ( mX - vec.mX ),
        ( mY - vec.mY ),
        ( mZ - vec.mZ )
    );
}

inline const Point3f Vector3f::operator +( const Point3f &pnt ) const
{
    return Point3f(
        ( mX + pnt.getX() ),
        ( mY + pnt.getY() ),
        ( mZ + pnt.getZ() )
    );
}

inline const Vector3f Vector3f::operator *( REAL scalar ) const
{
    return Vector3f(
        ( mX * scalar ),
        ( mY * scalar ),
        ( mZ * scalar )
    );
}

inline Vector3f & Vector3f::operator +=( const Vector3f &vec )
{
    *this = *this + vec;
    return *this;
}

inline Vector3f & Vector3f::operator -=( const Vector3f &vec )
{
    *this = *this - vec;
    return *this;
}

inline Vector3f & Vector3f::operator *=( REAL scalar )
{
    *this = *this * scalar;
    return *this;
}

inline const Vector3f Vector3f::operator /( REAL scalar ) const
{
    return Vector3f(
        ( mX / scalar ),
        ( mY / scalar ),
        ( mZ / scalar )
    );
}

inline Vector3f & Vector3f::operator /=( REAL scalar )
{
    *this = *this / scalar;
    return *this;
}

inline const Vector3f Vector3f::operator -( ) const
{
    return Vector3f(
        -mX,
        -mY,
        -mZ
    );
}


// Vector3  ==> Vector3f
inline Vector3f::Vector3f( const Vector3 &vec )
{
    mX = vec.getX();
    mY = vec.getY();
    mZ = vec.getZ();
}

// Vector3f ==> Vector3
inline Vector3f::operator Vector3() const
{
    return Vector3( mX, mY, mZ );
}


////////////////////////////////////////////////////////////////////////////////
// Point3f

inline Point3f::Point3f()
:
#ifndef __GNUC__
    d(0.0),
#endif
    mX(0.0),
    mY(0.0),
    mZ(0.0)
{}

inline Point3f::Point3f( const Point3f &vec )
{
    mX = vec.mX;
    mY = vec.mY;
    mZ = vec.mZ;
}

inline Point3f::Point3f( float _x, float _y, float _z )
{
    mX = _x;
    mY = _y;
    mZ = _z;
}

inline Point3f::Point3f( const Vector3f &vec )
{
    mX = vec.getX();
    mY = vec.getY();
    mZ = vec.getZ();
}

inline Point3f::Point3f( float scalar )
{
    mX = scalar;
    mY = scalar;
    mZ = scalar;
}

inline Point3f& Point3f::operator =( const Point3f &vec )
{
    mX = vec.mX;
    mY = vec.mY;
    mZ = vec.mZ;
    return *this;
}

inline Point3f& Point3f::setX( float _x )
{
    mX = _x;
    return *this;
}

inline float Point3f::getX( ) const
{
    return mX;
}

inline Point3f& Point3f::setY( float _y )
{
    mY = _y;
    return *this;
}

inline float Point3f::getY( ) const
{
    return mY;
}

inline Point3f& Point3f::setZ( float _z )
{
    mZ = _z;
    return *this;
}

inline float Point3f::getZ( ) const
{
    return mZ;
}

inline Point3f& Point3f::setElem( int idx, float value )
{
    *(&mX + idx) = value;
    return *this;
}

inline float Point3f::getElem( int idx ) const
{
    return *(&mX + idx);
}

inline float& Point3f::operator []( int idx )
{
    return *(&mX + idx);
}

inline float Point3f::operator []( int idx ) const
{
    return *(&mX + idx);
}

inline const Vector3f Point3f::operator -( const Point3f &pnt ) const
{
    return Vector3f(
        ( mX - pnt.mX ),
        ( mY - pnt.mY ),
        ( mZ - pnt.mZ )
    );
}

inline const Point3f Point3f::operator +( const Vector3f &vec ) const
{
    return Point3f(
        ( mX + vec.getX() ),
        ( mY + vec.getY() ),
        ( mZ + vec.getZ() )
    );
}

inline const Point3f Point3f::operator -( const Vector3f &vec ) const
{
    return Point3f(
        ( mX - vec.getX() ),
        ( mY - vec.getY() ),
        ( mZ - vec.getZ() )
    );
}

inline Point3f & Point3f::operator +=( const Vector3f &vec )
{
    *this = *this + vec;
    return *this;
}

inline Point3f & Point3f::operator -=( const Vector3f &vec )
{
    *this = *this - vec;
    return *this;
}

// Point3  ==> Point3f
inline Point3f::Point3f( const Point3 &pnt )
{
    mX = pnt.getX();
    mY = pnt.getY();
    mZ = pnt.getZ();
}

// Point3f ==> Point3
inline Point3f::operator Point3() const
{
    return Point3( mX, mY, mZ );
}

} // namespace col
